/******************************************************************
 *  MRRM's testbench - instruction fetch unit                     *
 *                                                                *
 *  This file is part of the MRRM project                         *
 *  <http://mrrm.googlecode.com/>                                 *
 *                                                                *
 *  Author(s):                                                    *
 *    -  Wu Jinkai                                                *
 *                                                                *
 ******************************************************************
 *                                                                *
 *  Copyright (C) 2010 AUTHORS                                    *
 *                                                                *
 *  This source file may be used and distributed without          *
 *  restriction provided that this copyright statement is not     *
 *  removed from the file and that any derivative work contains   *
 *  the original copyright notice and the associated disclaimer.  *
 *                                                                *
 *  MRRM is free software: you can redistribute it and/or modify  *
 *  it under the terms of the GNU General Public License as       *
 *  published by the Free Software Foundation, either version 3   *
 *  of the License, or (at your option) any later version.        *
 *                                                                *
 *  MRRM is distributed in the hope that it will be useful, but   *
 *  WITHOUT ANY WARRANTY; without even the implied warranty of    *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  *
 *  GNU General Public License for more details.                  *
 *                                                                *
 *  You should have received a copy of the GNU General Public     *
 *  License along with MRRM. If not, see                          *
 *  <http://www.gnu.org/licenses/>.                               *
 *                                                                *
 ******************************************************************/

`include "global.v"

module mrrm_test_if;
  
  parameter iw = `INSTRUCTION_WIDTH;
  parameter aw = `MEMORY_ADDR_WIDTH;

  // Interfaces
  // Memory interface
  wire [aw-1:0] imemaddr;
  reg [iw-1:0] imemdata;
  // IF interface
  reg [aw-1:0] F_predpc;
  wire [iw-1:0] f_insn;
  wire [aw-1:0] f_valp;
  wire [aw-1:0] f_predpc;
  // Halt signal
  wire halt;
  // EXE interface
  reg [2:0] E_itype;
  reg [1:0] E_isubtype;
  reg [3:0] E_ifun;
  reg [aw-1:0] E_valb;
  // MEM interface
  reg M_bch;
  reg [2:0] M_itype;
  reg [aw-1:0] M_valp;

mrrm_if t_mrrm_if(
	.imemaddr(imemaddr), .imemdata(imemdata),
	.F_predpc(F_predpc), .f_insn(f_insn), .f_valp(f_valp), .f_predpc(f_predpc),
	.halt(halt),
	.E_itype(E_itype), .E_isubtype(E_isubtype), .E_ifun(E_ifun), .E_valb(E_valb),
	.M_bch(M_bch), .M_itype(M_itype), .M_valp(M_valp)
	);
	
initial
  begin
    // Initial
    imemdata = 0;
    F_predpc = 0;
    E_itype = 0; // `I_REG = 3'b000
    E_isubtype =  0; // `S_ONE = 2'b00
    E_ifun = 0; // `F_AND = 4'b0000
    E_valb = 0;
    M_bch = 0;
    M_itype = 0; // `I_REG = 3'b000
    M_valp = 0;
    
    // Fetch instruction test
    #30 F_predpc = 32'b00010010001101000000101111001101; //12340bcd
    M_valp = 32'b00001011110011010001001000110100; //0bcd1234
    E_valb = 32'b00001011110011010000000000000000; //0bcd0000
    //MEM_PC
    #20 M_itype = `I_BXX;
    M_bch = 1'b0;   
    // Dissatisfy M_itype == `I_BXX
    #40 M_itype = `I_REG;   
    // Dissatisfy M_bch == 1'b0
    #20 M_itype = `I_BXX;
    #40 M_bch = 1'b1;
    
    //EXE_B
    #100 M_itype = 0; // `I_REG = 3'b000
    M_bch = 0;
    E_itype = `I_REG;
    E_isubtype = `S_TWO;
    E_ifun = `F_JUMP;
    // Dissatisfy E_itype == `I_REG
    #40 E_itype = `I_IMM;
    // Dissatisfy E_isubtype == `S_TWO
    #20 E_itype = `I_REG;
    #40 E_isubtype = `S_ONE;
    // Dissatisfy E_ifun == `F_JUMP
    #20 E_isubtype = `S_TWO;
    #40 E_ifun = `F_AND;
    
    // New PC test
    // now imemaddr = 12340bcd, so f_valp shoulb be 12340bd1
    // now f_predpc shoulb be 12340bd9
    #100 imemdata = 32'b10100000000000000000000000000010; //a0000002
    // Dissatisfy f_insn[31:29] == `I_BXX
    #40 imemdata = 32'b10000000000000000000000000000010; //80000002
  
    // Halt test
    #100 imemdata = 32'b11000000000000000000000000000000; //c0000000
   
    #100 $stop;

  end
  
initial
  begin
    $monitor("Time@%d, imemaddr=%h, f_insn=%h, f_valp=%h, f_predpc=%h, halt=%d",
      $time, imemaddr, f_insn, f_valp, f_predpc, halt
    );
  end

endmodule